---
title: Router Instruments
subtitle: Standard metric instruments for the router's request lifecycle
description: Reference of standard metric instruments for the request lifecycle of GraphOS Router and Apollo Router Core. Consumable via the router's metrics exporters.
context:
  - telemetry
redirectFrom:
  - /graphos/routing/observability/telemetry/instrumentation/standard-instruments
---

## Standard metric instruments

GraphOS Router and Apollo Router Core provide a set of standard router instruments that expose detailed information about the router's request lifecycle. You can consume the metrics they capture by configuring a [metrics exporter](/router/configuration/telemetry/exporters/metrics/overview).

Standard router instruments are different than OpenTelemetry (OTel) instruments or custom instruments:

- Router instruments provide standard metrics about the router request lifeycle and have names starting with `apollo.router` or `apollo_router`.
- OTel instruments provide metrics about the HTTP lifecycle and have names starting with `http`.
- Custom instruments provide customized metrics about the router request lifecycle.

The rest of this reference lists the available standard router instruments.

### Measuring router overhead

Measuring overhead in the router can be challenging because it consists of multiple components, each executing tasks in parallel. Subgraph latency, cache performance, and plugins influence performance and have the potential to cause back pressure. Limitations to CPU, memory, and network bandwidth can all create bottlenecks that hinder request processing. External factors such as request rate and operation complexity heavily affect the router’s overall load.

You can find the activity of a particular request in its trace spans. Spans have the following attributes:
  - <code>busy_ns</code> - time in which the span is actively executing
  - <code>idle_ns</code> - time in which the span is alive, but not actively executing

These attributes represent how a span spends time (in nanoseconds) over its lifetime. Your APM provider can likely use this trace data to generate synthetic metrics which you can then create an approximation of.

#### Router overhead metric

The `apollo.router.overhead` histogram provides a more direct measurement of router processing overhead. This metric tracks the time the router spends on tasks other than waiting for downstream HTTP requests—including GraphQL parsing, validation, query planning, response composition, and plugin execution.

The overhead calculation excludes time spent waiting for downstream HTTP services (subgraphs and connectors), giving you visibility into the router's actual processing time versus downstream latency. This metric helps identify when the router itself is a bottleneck versus when delays are caused by downstream services.

<Note>

Important considerations for router overhead metrics:

- **Version variability**: Router overhead might vary between router versions. For example, a correctness fix or security improvement might result in higher overhead. Always compare overhead measurements within the same router version.

- **Configuration requirements**: For meaningful overhead measurements, configure [operation limits](/router/configuration/operation-limits) and [traffic shaping](/router/configuration/traffic-shaping). Without these controls, unbounded request complexity or traffic spikes can skew overhead measurements.

- **CPU saturation**: High overhead values often indicate CPU saturation. When the router's CPU resources are exhausted, processing time increases significantly. Monitor CPU utilization alongside overhead metrics to identify resource constraints.

- **Coprocessor requests:** Coprocessor request time is currently included in the overhead calculation. In a future release, coprocessor time might be excluded similar to subgraphs and connectors.

</Note>

Default attributes:
- `subgraph.active_requests`: A boolean indicating whether any subgraph requests were active at the time the overhead was calculated. This attribute is critical for filtering meaningful overhead measurements.

  For operations that stream results (such as queries with `@defer`), the overhead metric becomes less meaningful because the router is in a waiting state instead of actively processing. When analyzing overhead to identify router processing bottlenecks, exclude measurements where `subgraph.active_requests: true` to focus only on pure router processing time without subgraph wait time interference.

Configuration example:

```yaml title="router.yaml"
telemetry:
  instrumentation:
    instruments:
      router:
        apollo.router.overhead: true
```

You can attach custom attributes using [router selectors](/router/configuration/telemetry/instrumentation/selectors#router).

### GraphQL

- `apollo.router.graphql_error` - counts GraphQL errors in responses. Also counts errors which occur during the response validation phase, which are represented in client responses as `extensions.valueCompletion` instead of actual GraphQL errors. Attributes:
  - `code`: error code, including `RESPONSE_VALIDATION_FAILED` in the case of a value completion error.

### Session

- `apollo.router.session.count.active` - Number of in-flight GraphQL requests

### Cache

- `apollo.router.cache.size` — Number of entries in the cache
- `apollo.router.cache.hit.time` - Time to hit the cache in seconds
- `apollo.router.cache.hit.time.count` - Number of cache hits
- `apollo.router.cache.miss.time` - Time to miss the cache in seconds
- `apollo.router.cache.miss.time.count` - Number of cache misses
- `apollo.router.cache.storage.estimated_size` - The estimated storage size of the cache in bytes (query planner in memory only).

All cache metrics listed above have the following attributes:

- `kind`: the cache being queried (`apq`, `query planner`, `introspection`)
- `storage`: The backend storage of the cache (`memory`, `redis`)

### Redis Cache

When using Redis as a cache backend, additional Redis-specific metrics are available:

- `apollo.router.cache.redis.clients` - Number of Redis clients active
- `apollo.router.cache.redis.command_queue_length` - Number of Redis commands buffered and not yet sent
- `apollo.router.cache.redis.commands_executed` - Total number of Redis commands executed
- `apollo.router.cache.redis.redelivery_count` - Number of Redis command redeliveries due to connection issues
- `apollo.router.cache.redis.errors` - Number of Redis errors by error type and cache kind
- `experimental.apollo.router.cache.redis.latency_avg` - Average Redis command latency in seconds
- `experimental.apollo.router.cache.redis.network_latency_avg` - Average Redis network latency in seconds  
- `experimental.apollo.router.cache.redis.request_size_avg` - Average Redis request size in bytes
- `experimental.apollo.router.cache.redis.response_size_avg` - Average Redis response size in bytes

All Redis metrics, except for `apollo.router.cache.redis.clients`, include the following attribute:

- `kind`: the cache being queried (`apq`, `query planner`, `introspection`, `entity`)

The `apollo.router.cache.redis.errors` metric also includes an `error_type` attribute with possible values:
- `config` - Configuration errors (invalid Redis settings)
- `auth` - Authentication errors (wrong credentials)
- `routing` - Cluster routing errors
- `io` - Network I/O errors
- `invalid_command` - Invalid Redis commands
- `invalid_argument` - Invalid command arguments
- `not_found` - Missing key in Redis
- `url` - Invalid Redis URL format
- `protocol` - Redis protocol errors
- `tls` - TLS/SSL connection errors
- `canceled` - Canceled operations
- `unknown` - Unknown errors
- `timeout` - Operation timeouts
- `cluster` - Redis cluster state errors
- `parse` - Data parsing errors
- `sentinel` - Redis Sentinel errors
- `backpressure` - Backpressure/overload errors

### Coprocessor

- `apollo.router.operations.coprocessor` - Total operations with coprocessors enabled.
  - `coprocessor.succeeded`: bool
  - `coprocessor.stage`: string (`RouterRequest`, `RouterResponse`, `SubgraphRequest`, `SubgraphResponse`)

- `apollo.router.operations.coprocessor.duration` - Time spent waiting for the coprocessor to answer, in seconds.
  - `coprocessor.stage`: string (`RouterRequest`, `RouterResponse`, `SubgraphRequest`, `SubgraphResponse`)

### Performance

- `apollo_router_schema_load_duration` - Time spent loading the schema in seconds.

### Query planning

- `apollo.router.query_planning.warmup.duration` - Time spent warming up the query planner queries in seconds.
- `apollo.router.query_planning.plan.duration` - Histogram of plan durations isolated to query planning time only.
- `apollo.router.query_planning.total.duration` - Histogram of plan durations including queue time.
- `apollo.router.query_planning.plan.evaluated_plans` - Histogram of the number of evaluated query plans.

### Compute jobs

- `apollo.router.compute_jobs.queued` - A gauge of the number of jobs queued for the thread pool dedicated to CPU-heavy components like GraphQL parsing and validation, and the query planner.
- `apollo.router.compute_jobs.queue_is_full` - A counter of requests rejected because the queue was full.
- `apollo.router.compute_jobs.duration` - A histogram of time spent in the compute pipeline by the job, including the queue and query planning.
  - `job.type`: (`QueryPlanning`, `QueryParsing`, `Introspection`)
  - `job.outcome`: (`ExecutedOk`, `ExecutedError`, `ChannelError`, `RejectedQueueFull`, `Abandoned`)
- `apollo.router.compute_jobs.queue.wait.duration` - A histogram of time spent in the compute queue by the job.
  - `job.type`: (`QueryPlanning`, `QueryParsing`, `Introspection`)
- `apollo.router.compute_jobs.execution.duration` - A histogram of time spent to execute job (excludes time spent in the queue).
  - `job.type`: (`QueryPlanning`, `QueryParsing`, `Introspection`)
- `apollo.router.compute_jobs.active_jobs` - A gauge of the number of compute jobs being processed in parallel.
  - `job.type`: (`QueryPlanning`, `QueryParsing`, `Introspection`)

### Uplink

<Tip>

[Learn more about Apollo Uplink.](/federation/managed-federation/uplink/)

</Tip>

- `apollo.router.uplink.fetch.duration.seconds` - Uplink request duration, attributes:
  - `url`: The Uplink URL that was polled
  - `query`: The query that the router sent to Uplink (`SupergraphSdl` or `License`)
  - `kind`: (`new`, `unchanged`, `http_error`, `uplink_error`)
  - `code`: The error code depending on type (if an error occurred)
  - `error`: The error message (if an error occurred)
- `apollo.router.uplink.fetch.count.total`
  - `status`: (`success`, `failure`)
  - `query`: The query that the router sent to Uplink (`SupergraphSdl` or `License`)

<Note>

The initial call to Uplink during router startup is not reflected in metrics.

</Note>

### Subscriptions

<Tip>

[Learn more about subscriptions.](/router/executing-operations/subscription-support/)

</Tip>

- `apollo.router.opened.subscriptions` - Number of different opened subscriptions (not the number of clients with an opened subscriptions in case it's deduplicated). This metric contains `graphql.operation.name` label to know exactly which subscription is still opened.
- `apollo.router.skipped.event.count` - Number of subscription events that has been skipped because too many events have been received from the subgraph but not yet sent to the client.

### Batching

- `apollo.router.operations.batching` - A counter of the number of query batches received by the router.
- `apollo.router.operations.batching.size` - A histogram tracking the number of queries contained within a query batch.

### GraphOS Studio

- `apollo.router.telemetry.studio.reports` - The number of reports submitted to GraphOS Studio by the router.
  - `report.type`: The type of report submitted: "traces" or "metrics"
  - `report.protocol`: Either "apollo" or "otlp", depending on the otlp_tracing_sampler configuration.

### Telemetry

- `apollo.router.telemetry.batch_processor.errors` - The number of errors encountered by exporter batch processors.
  - `name`: One of `apollo-tracing`, `datadog-tracing`, `jaeger-collector`, `otlp-tracing`, `zipkin-tracing`.
  - `error`: One of `channel closed`, `channel full`.

- `apollo.router.telemetry.metrics.cardinality_overflow` - A count of how often a telemetry metric hit otel's hard cardinality limit.

### Internals

- `apollo.router.pipelines` - The number of request pipelines active in the router
  - `schema.id` - The Apollo Studio schema hash associated with the pipeline.
  - `launch.id` - The Apollo Studio launch id associated with the pipeline (optional).
  - `config.hash` - The hash of the configuration

### Server

- `apollo.router.open_connections` - The number of open connections to the Router.
  - `schema.id` - The Apollo Studio schema hash associated with the pipeline.
  - `launch.id` - The Apollo Studio launch id associated with the pipeline (optional).
  - `config.hash` - The hash of the configuration.
  - `server.address` - The address that the router is listening on.
  - `server.port` - The port that the router is listening on if not a unix socket.
  - `http.connection.state` - Either `active` or `terminating`.
